import 'dart:async';
import 'dart:io';

import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:path_provider/path_provider.dart';
void main() => runApp(App());

class App extends StatefulWidget {
  App({Key key}) : super(key: key);

  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  TextEditingController c = TextEditingController();
  TextEditingController cc = TextEditingController();

  @override
  void initState() {
    super.initState();
    findPath();
  }

  findPath() async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;
    print('------------------------');
    print(tempPath);
    print('------------------------');
    return tempPath;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Builder(builder: (context) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              CupertinoTextField(
                controller: cc,
                placeholder: '日志地址',
              ),
              CupertinoTextField(
                controller: c,
                placeholder: '频道',
              ),
              FlatButton(
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
                    return MyApp(c.text, cc.text);
                  }));
                },
                child: Text('跳'),
              ),
            ],
          );
        }),
      ),
    );
  }
}

class MyApp extends StatefulWidget {
  final String channel;
  final String log;
  MyApp(this.channel, this.log);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isInChannel = false;
  final _infoStrings = <String>[];
  double blurLevel = 0;
  double colorLevel = 0;
  double redLevel = 0;
  double eyeLevel = 0;
  double toothLevel = 0;
  double eyeLargeLevel = 0;
  double chinkThinLevel = 0;
  double chinLevel = 0;
  double foreheadLevel = 0;
  double noseLevel = 0;
  double mouthLevel = 0;
  static final _sessions = List<VideoSession>();
  String dropdownValue = 'Off';

  final List<String> voices = [
    'Off',
    'Oldman',
    'BabyBoy',
    'BabyGirl',
    'Zhubajie',
    'Ethereal',
    'Hulk'
  ];

  /// remote user list
  final _remoteUsers = List<int>();

  @override
  void initState() {
    super.initState();

    _initAgoraRtcEngine();
    _addAgoraEventHandlers();
    joinChannel();
    findPath();
  }

  @override
  void dispose() {
    AgoraRtcEngine.leaveChannel();
    AgoraRtcEngine.destroy();
    super.dispose();
  }

  findPath() async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;
    AgoraRtcEngine.setLogFile(widget.log);
    print('------------------------');
    print(tempPath);
    print('------------------------');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Agora Flutter SDK'),
      ),
      body: FutureBuilder<PermissionStatus>(
        future: Permission.camera.request(),
        builder: (context, snapshot) {
          if (snapshot.hasData && snapshot.data == PermissionStatus.granted)
            return Container(
              child: Column(
                children: [
                  Container(height: 320, child: _viewRows()),
                  Text('$_remoteUsers'),
                  Text('频道： ${widget.channel}'),
                  Text('日志地址： ${widget.log}'),
                  OutlineButton(
                    child: Text(
                      _isInChannel ? 'Leave Channel' : 'Join Channel',
                      style: textStyle,
                    ),
                    onPressed: _toggleChannel,
                  ),
                  Expanded(
                    child: ListView(
                      children: <Widget>[
                        Text('磨皮'),
                        Slider(value: blurLevel, onChanged: _handleBlur),
                        Text('美白'),
                        Slider(value: colorLevel, onChanged: _handleColor),
                        Text('红润'),
                        Slider(value: redLevel, onChanged: _handleRed),
                        Text('亮眼'),
                        Slider(value: eyeLevel, onChanged: _handleEye),
                        Text('美牙'),
                        Slider(value: toothLevel, onChanged: _handleTooth),
                        Text('大眼'),
                        Slider(
                          value: eyeLargeLevel,
                          onChanged: _handleEeyeLarge,
                        ),
                        Text('瘦脸'),
                        Slider(
                          value: chinkThinLevel,
                          onChanged: _handleChinkThin,
                        ),
                        Text('下巴'),
                        Slider(
                          value: chinLevel,
                          onChanged: _handleChin,
                        ),
                        Text('额头'),
                        Slider(
                          value: foreheadLevel,
                          onChanged: _handleForehead,
                        ),
                        Text('瘦鼻'),
                        Slider(
                          value: noseLevel,
                          onChanged: _handleNose,
                        ),
                        Text('嘴形'),
                        Slider(
                          value: mouthLevel,
                          onChanged: _handleMouth,
                        ),
                        Container(height: 100, child: _voiceDropdown()),
//                          Container(child: _buildInfoList()),
                      ],
                    ),
                  ),
                ],
              ),
            );
          else
            return Center(child: CupertinoActivityIndicator());
        },
      ),
    );
  }

  Widget _voiceDropdown() {
    return Scaffold(
      body: Center(
        child: DropdownButton<String>(
          value: dropdownValue,
          onChanged: (String newValue) {
            setState(() {
              dropdownValue = newValue;
              VoiceChanger voice =
                  VoiceChanger.values[(voices.indexOf(dropdownValue))];
              AgoraRtcEngine.setLocalVoiceChanger(voice);
            });
          },
          items: voices.map<DropdownMenuItem<String>>((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
        ),
      ),
    );
  }

  Future<void> _initAgoraRtcEngine() async {
    await AgoraRtcEngine.create('853eb3c31d7644a8bdb8dbabcf6f3f84');

    AgoraRtcEngine.enableVideo();
    AgoraRtcEngine.enableAudio();

    if (Platform.isIOS) {
      //涉及到美颜，需要直播模式。通信模式不能直接使用美颜返回的纹理
      //ios设置一下，android原生里面设置了
      //这里设置了直播模式会异常
      AgoraRtcEngine.setChannelProfile(ChannelProfile.Communication);
    }

    VideoEncoderConfiguration config = VideoEncoderConfiguration();
    config.orientationMode = VideoOutputOrientationMode.FixedPortrait;
    AgoraRtcEngine.setVideoEncoderConfiguration(config);

    AgoraRtcEngine.setClientRole(ClientRole.Broadcaster); // 设置直播身份(主播)
  }

  void _addAgoraEventHandlers() {
    AgoraRtcEngine.onVideoSizeChanged = (uid, width, height, rotation) {
      print('$uid $width $height $rotation');
    };

    AgoraRtcEngine.onJoinChannelSuccess =
        (String channel, int uid, int elapsed) {
      setState(() {
        String info = 'onJoinChannel: ' + channel + ', uid: ' + uid.toString();
        _infoStrings.add(info);
      });
    };

    AgoraRtcEngine.onLeaveChannel = () {
      setState(() {
        _infoStrings.add('onLeaveChannel');
        _remoteUsers.clear();
      });
    };

    AgoraRtcEngine.onUserJoined = (int uid, int elapsed) {
      setState(() {
        String info = 'userJoined: ' + uid.toString();
        _infoStrings.add(info);
        _remoteUsers.add(uid);
      });
    };

    AgoraRtcEngine.onUserOffline = (int uid, int reason) {
      setState(() {
        String info = 'userOffline: ' + uid.toString();
        _infoStrings.add(info);
        _remoteUsers.remove(uid);
      });
    };

    AgoraRtcEngine.onFirstRemoteVideoFrame =
        (int uid, int width, int height, int elapsed) {
      setState(() {
        String info = 'firstRemoteVideo: ' +
            uid.toString() +
            ' ' +
            width.toString() +
            'x' +
            height.toString();
        _infoStrings.add(info);
      });
    };
  }

  void _toggleChannel() {
    setState(() {
      if (_isInChannel) {
        _isInChannel = false;
        AgoraRtcEngine.leaveChannel();
        AgoraRtcEngine.stopPreview();
      } else {
        _isInChannel = true;
        AgoraRtcEngine.startPreview();
        joinChannel();
      }
    });
  }

  joinChannel() {
    AgoraRtcEngine.joinChannel(null, widget.channel ?? 'channel', null, 0);
  }

  Widget _viewRows() {
    return Row(
      children: <Widget>[
        for (final widget in _renderWidget) Container(child: widget, width: 150)
      ],
    );
  }

  Iterable<Widget> get _renderWidget sync* {
    yield AgoraRenderWidget(0, local: true, preview: true);

    for (final uid in _remoteUsers) {
      yield Stack(
        children: <Widget>[
          AgoraRenderWidget(uid),
          Text(
            '$uid',
            style: TextStyle(color: Colors.white),
          )
        ],
      );
    }
  }

  static TextStyle textStyle = TextStyle(fontSize: 18, color: Colors.blue);

  Widget _buildInfoList() {
    return ListView.builder(
      padding: const EdgeInsets.all(8.0),
      itemExtent: 24,
      itemBuilder: (context, i) {
        return ListTile(
          title: Text(_infoStrings[i]),
        );
      },
      itemCount: _infoStrings.length,
    );
  }

  Future<void> _handleChinkThin(double value) async {
    setState(() {
      chinkThinLevel = value;
    });
    await AgoraRtcEngine.fuSetCheekThinning(chinkThinLevel * 10);
  }

  void _handleBlur(double value) async {
    setState(() {
      blurLevel = value;
    });
    await AgoraRtcEngine.fuSetBlurLevel(blurLevel * 10);
  }

  void _handleColor(double value) async {
    setState(() {
      colorLevel = value;
    });
    await AgoraRtcEngine.fuSetColorLevel(colorLevel * 10);
  }

  void _handleRed(double value) async {
    setState(() {
      redLevel = value;
    });
    await AgoraRtcEngine.fuSetRedLevel(redLevel * 10);
  }

  void _handleEye(double value) async {
    setState(() {
      eyeLevel = value;
    });
    await AgoraRtcEngine.fuSetEyeBright(eyeLevel * 10);
  }

  void _handleTooth(double value) async {
    setState(() {
      toothLevel = value;
    });
    await AgoraRtcEngine.fuSetToothWhiten(toothLevel * 10);
  }

  void _handleEeyeLarge(double value) async {
    setState(() {
      eyeLargeLevel = value;
    });
    await AgoraRtcEngine.fuSetEyeEnlarge(eyeLargeLevel * 10);
  }

  void _handleChin(double value) async {
    setState(() {
      chinLevel = value;
    });
    await AgoraRtcEngine.fuSetIntensityChin(chinLevel * 10);
  }

  void _handleForehead(double value) async {
    setState(() {
      foreheadLevel = value;
    });
    await AgoraRtcEngine.fuSetIntensityForehead(foreheadLevel * 10);
  }

  void _handleNose(double value) async {
    setState(() {
      noseLevel = value;
    });
    await AgoraRtcEngine.fuSetIntensityNose(noseLevel * 10);
  }

  void _handleMouth(double value) async {
    setState(() {
      mouthLevel = value;
    });
    await AgoraRtcEngine.fuSetIntensityMouth(mouthLevel * 10);
  }
}

class VideoSession {
  int uid;
  Widget view;
  int viewId;

  VideoSession(int uid, Widget view) {
    this.uid = uid;
    this.view = view;
  }
}
